package model.map;

import utilities.Archive;
import main.Log;
import utilities.*;
/**
 * A class to abstract movement, such that the tile shape can be changed.
 */
public class HexLocationProjection extends LocationProjection {
	
	protected World world = World.getInstance();
	
	/**
	 * Returns the location that a movement of Direction will result in, based on the passed in location
	 * Will return the original location if the changed location is out of the bounds of the current map.
	 * @return The location that the movement will result in.
	 */
	public Location projectLocation(Location location, Direction direction)
	{
		
		Location newlocation;
		
		switch(direction)
		{
			case SW:
			{
				
				newlocation = new Location(location.getX() + 1, location.getY());
				
				if(world.currentMapExists(newlocation))
				{
					return newlocation;
				} else
				{
					return location;
				}
			}
			
			case S:
			{
				newlocation = new Location(location.getX() + 1, location.getY() + 1);
				
				if(world.currentMapExists(newlocation))
				{
					return newlocation;
				} else
				{
					return location;
				}
			}
			
			case SE:
			{
				newlocation = new Location(location.getX(), location.getY() + 1);
				
				if(world.currentMapExists(newlocation))
				{
					return newlocation;
				} else
				{
					return location;
				}
			}
			case E: 
			{
				newlocation = new Location(location.getX() - 1, location.getY() + 1);
				
				if(world.currentMapExists(newlocation))
				{
					return newlocation;
				} else
				{
					return location;
				}
			}
			case W: 
			{
				newlocation = new Location(location.getX() + 1, location.getY() - 1);
				
				if(world.currentMapExists(newlocation))
				{
					return newlocation;
				} else
				{
					return location;
				}
			}
			case NW: 
			{
				newlocation = new Location(location.getX(), location.getY() - 1);
				
				if(world.currentMapExists(newlocation))
				{
					return newlocation;
				} else
				{
					return location;
				}
			}
			case N: 
			{
				newlocation = new Location(location.getX() - 1, location.getY() - 1);
				
				if(world.currentMapExists(newlocation))
				{
					return newlocation;
				} else
				{
					return location;
				}
			}
			case NE: 
			{
				newlocation = new Location(location.getX() - 1, location.getY());
				
				if(world.currentMapExists(newlocation))
				{
					return newlocation;
				} else
				{
					return location;
				}
			}
			default: Log.out(Log.MODEL, "HexLocationProjection: returned NULL?"); return null;
		}
	}
	
	/**
	 * Returns the location that a movement of length tiles, in a Direction will result in, based on the passed in location
	 * Will return the original location if the changed location is out of the bounds of the current map.
	 * @return The location that the movement will result in.
	 */
	public Location projectLocation(Location location, Direction direction, int length)
	{
		
		Location newlocation;
		
		switch(direction)
		{
			case SW: 
			{
				newlocation = new Location(location.getX() + length, location.getY());
				
				if(world.currentMapExists(newlocation))
				{
					return newlocation;
				} else
				{
					return location;
				}
			}
			case S: 
			{
				newlocation = new Location(location.getX() + length, location.getY() + length);
				
				if(world.currentMapExists(newlocation))
				{
					return newlocation;
				} else
				{
					return location;
				}
			}
			case SE: 
			{
				newlocation = new Location(location.getX(), location.getY() + length);
				
				if(world.currentMapExists(newlocation))
				{
					return newlocation;
				} else
				{
					return location;
				}
			}
			case E: 
			{
				newlocation = new Location(location.getX() - length, location.getY() + length);
				
				if(world.currentMapExists(newlocation))
				{
					return newlocation;
				} else
				{
					return location;
				}
			}
			case W: 
			{
				newlocation = new Location(location.getX() + length, location.getY() - length);
				
				if(world.currentMapExists(newlocation))
				{
					return newlocation;
				} else
				{
					return location;
				}
			}
			case NW: 
			{
				newlocation = new Location(location.getX(), location.getY() - length);
				
				if(world.currentMapExists(newlocation))
				{
					return newlocation;
				} else
				{
					return location;
				}
			}
			case N: 
			{
				newlocation = new Location(location.getX() - length, location.getY() - length);
				
				if(world.currentMapExists(newlocation))
				{
					return newlocation;
				} else
				{
					return location;
				}
			}
			case NE: 
			{
				newlocation = new Location(location.getX() - length, location.getY());
				
				if(world.currentMapExists(newlocation))
				{
					return newlocation;
				} else
				{
					return location;
				}
			}
			default:
			{
				Log.out(Log.MODEL, "HexLocationProjection: returned NULL?"); return null;
			}
		}
	}
	
	public Archive save() {
		Archive archive = super.save();
		
		return archive;
	}
	
	public void load(Archive archive) {
		super.load(archive);
	}
}